package Learn;

import Exe.Student;

import java.util.HashMap;

public class HashMapDemo1 {
    //Map   -> HashMap  ->LinkedHashMap
    //      -> Hashtable ->Properties
    //      ->TreeMap

    //HashMap
    //原理 底层还是哈希表
    //底层原理
    //JDK8之前
    //默认创建一个长度16 默认因子为0.75数组 名字table
    //创建一个Entry对象  根据 键值对的键来判断计算哈希值 跟值无关

    //int index=(数组长度-1)&哈希值；

    //判断位置是否是null  如果是那么存入

    //不是null 调用equals 比较键的属性值  一样覆盖  不一样 存入数组形成链表
    //JDK8之前 新元素存入数组 老元素挂在下面
    //之后新元素挂在老元素下面

    //如果数组内元素个数大于长度*默认因子的时候 数组进行扩容成原来数组的两倍
    //当链表的长度大于8并且数组长度大于等于64时，链表转化成红黑树的形式 提高查找效率

    //（如果集合存储的是自定义对象，必须重写hashcode和equals方法）
    public static void main(String[] args) {
        HashMap<Student,String> map=new HashMap<>();
        Student s1=new Student("Wangyufei",20);
        Student s2=new Student("goushuyu",21);


        map.put(s1,"hebei");
        map.put(s2,"fuping");

        map.forEach((s11,s22)-> System.out.println(s11+" "+s22));

    }

    //底层原理
    //方法后面有向上的箭头 代表它是重写的父类或者是接口中的方法
    //右箭头代表的是继承（实现）的该类（接口）的方法 点击会跳转到父类或者接口当中

    //put 方法
    //参数一：键的哈希值
    //二：键
    //三：值
    //四：当前元素是否保留 默认是false：老元素的值不保留 直接进行覆盖      true： 保留
    //五：暂时没用

    //putVal添加值的方法里定义了一个新的局部变量也叫tab 记录哈希表中数组的地址值
    //而成员位置有一个table 成员位置的table在堆区 存元素的时候会多次用到table 而去堆区找的话浪费时间
    //用空间换时间 在栈区创建tab存储成员变量table  能节省时间
    //如果是第一次添加 底层默认创造一个长度16 加载因子0.75的啥机子
    //不是的话看是否达到了扩容的条件 如果没达到 不做操作 达到了 扩容 转移数据到新数组

    //具体过程看源码

}
